<template>
    <view id="lswiperBox" class="h-full">
        <scroll-view :style="{ height: height + 'px' }" v-if="height" :scroll-y="true" id="lswiper"
            refresher-enabled="true" :refresher-triggered="triggered" :refresher-threshold="100"
            @refresherrefresh="onRefresh" @refresherrestore="onRestore" @refresherabort="onAbort">

            <slot :list="data.list"></slot>
            <view v-if="!data.list.length" class="mt-10 flex flex-col justify-center items-center">
                <u-image width="240" height="240" :src="icon"></u-image>
                <view class="text-center text-gray-400">暂时没有数据</view>
            </view>
            <view id="loadmore" class="text-center p-3 text-gray-400" :class="{ 'opacity-0': !data.list.length }">
                <text v-if="!data.more">——没有更多数据了——</text>
                <text v-else-if="data.loadmore">——加载中——</text>
                <text v-else-if="data.loaderror">——请求失败——</text>
                <text v-else>——上拉加载更多——</text>
            </view>

        </scroll-view>
    </view>
</template>
<script setup lang="ts">
import { onMounted, getCurrentInstance, onUnmounted, reactive } from 'vue';
import { ref, nextTick } from 'vue';
import icon from "@/assets/img/data.png"

const props = withDefaults(defineProps<{
    request: ({ page, limit }: { page: number, limit: number, [key: string]: any }) => Promise<any>
}>(), {
    request: () => Promise.resolve()
})
const height = ref(0)
// 是否已经被触发
const triggered = ref(false), data = reactive({
    page: 0,
    limit: 10,
    list: [],
    more: true,
    loadmore: false,
    loaderror: false
})
// 触发
function onRefresh() {
    if (triggered.value) return;
    triggered.value = true
    data.page = 1
    data.more = true
    send(() => data.list = [])

}
// 复位
function onRestore() {
}
// 中断
function onAbort() {
}
const obServe: UniApp.IntersectionObserver = uni.createIntersectionObserver(getCurrentInstance()), query = uni.createSelectorQuery().in(getCurrentInstance());
const getRect = (id: string, call: (res: any) => void) => {
    query.select(id).boundingClientRect(call).exec()
}
onMounted(() => {
    getRect("#lswiperBox", (result) => {
        height.value = result.height
        nextTick(() => {
            // onRefresh()
            obServe.relativeTo("#lswiper").observe("#loadmore", (res) => {
                if (res.intersectionRatio && data.more) {
                    data.page++
                    data.loadmore = true
                    send();
                }
            })
        })
    })
})

onUnmounted(() => {
    obServe.disconnect()
})

const send = (successCall?: Function, errorCall?: Function) => {
    props.request({ page: data.page, limit: data.limit }).then(res => {
        successCall && successCall()
        data.list = data.list.concat(res.list)
        data.more = data.list.length < res.total;
        data.loaderror = false;
    }).catch(() => {
        data.loaderror = true
        errorCall && errorCall()
    }).finally(() => {
        triggered.value = false
        data.loadmore = false
    })
}
defineExpose({
    onRefresh
})
</script>
<style lang="scss">
l-swiper {
    @apply block overflow-hidden;
}
</style>